<template>
  <div>
    <backContainer v-if="componentType == 2">
      <div class="card" v-loading="loading">
        <!-- 顶部行 -->
        <div class="titleLine flexBet">
          <ancestorsNameDeal
            :text="ancestorsName"
            :maxLength="50"
            class="title shou"
          >
          </ancestorsNameDeal>
          <div class="btns flexColCenter">
            <!-- <div class="btn flexColCenter flexCen shou" @click="importTopic">
              <svg-icon class-name="btn_icon" icon-class="add_svg" />
              <div>批量导入试题</div>
            </div> -->
            <div
              class="btn flexColCenter flexCen shou"
              @click="importTheQuestionBank"
            >
              <svg-icon class-name="btn_icon" icon-class="muttle_svg" />
              <div>导入题库</div>
            </div>
          </div>
        </div>
        <!-- 检查区 -->
        <div class="flexBet checkBox">
          <!-- 输入区 -->
          <div
            class="edit_texteara"
            ref="left"
            @mouseenter="onEnter('left')"
            @mouseleave="onLeave"
          >
            <div class="edit_texteara_titleline flexBet">
              <div class="left">输入区</div>
              <div
                class="right shou"
                @click="
                  topicImportEnterTheSpecificationOpen =
                    !topicImportEnterTheSpecificationOpen
                "
              >
                输入规范
              </div>
            </div>
            <div>
              <wangEditor
                :action="action"
                @scroll="wangEditorScroll"
                ref="editor"
                @Blur="Blur"
                :isgetIndex="3"
                :editorValue.sync="content"
                height="calc(100vh - 328px)"
              />
            </div>
          </div>
          <!-- 检查区 -->
          <div
            class="topicBox"
            ref="right"
            @mouseenter="onEnter('right')"
            @mouseleave="onLeave"
          >
            <div class="topicBox_titleline flexBet">
              <div class="left">
                检查区<span>(总计{{ topicsShowArr.length }}道题目)</span>
              </div>
            </div>
            <div class="flex error" v-if="errorTopicIndexs.length > 0">
              <div class="error_txt">
                {{ errorTopicIndexs.length }}道错误试题，请参照例题修改
              </div>
              <div
                class="next"
                @click="scrollToElement('cur')"
                v-if="errorTopicIndexs.length == 1"
              >
                查看错误
              </div>
              <div
                class="prev"
                @click="scrollToElement('prev')"
                v-if="errorCurIndex > 0 && errorTopicIndexs.length > 1"
              >
                查看上一处
              </div>
              <div
                class="next"
                @click="scrollToElement('next')"
                v-if="
                  errorCurIndex < errorTopicIndexs.length - 1 &&
                  errorTopicIndexs.length > 1
                "
              >
                查看下一处
              </div>
            </div>
            <div
              class="topicContain"
              ref="scrollContainer"
              @scroll="handleScroll"
              v-show="topicsShowArr.length > 0"
            >
              <div
                :id="`topic${index}`"
                :ref="`topic${index}`"
                class="topic"
                v-for="(item, index) in topicsShowArr"
                :key="index"
              >
                <!-- 题目 -->
                <div
                  v-if="difficultys.includes(item.difficulty[0])"
                  class="topicTitle"
                  v-html="
                    `<p>${index + 1} / ${topicsShowArr.length}.

                      <span class='color_orange'>【${topicType[item.type]}】
                    </span>
                    <span class='difficulty_item ${
                      difficultyBgClass[item.difficulty[0]]
                    }'>
                    ${item.difficulty[0]}
                    </span>${$renderedDescription(item.question.slice(3))}`
                  "
                ></div>
                <div
                  v-else
                  class="topicTitle"
                  v-html="
                    `<p>${index + 1} / ${topicsShowArr.length}.

                      <span class='color_orange'>【${topicType[item.type]}】
                    </span>
                    ${$renderedDescription(item.question.slice(3))}`
                  "
                ></div>
                <!-- 选项 -->
                <div
                  class="topicOptions"
                  v-if="item.type == 'multi_choice' || item.type == 'choice'"
                >
                  <div
                    class="topicOptionItem"
                    v-for="(option, optionIndex) in item.options"
                    :key="optionIndex"
                  >
                    <p
                      class="topicOptionA"
                      v-html="$renderedDescription(option)"
                    ></p>
                  </div>
                </div>
                <!-- 答案 -->
                <div class="topicAnswer">
                  <p
                    class="topicAnswerText"
                    v-html="$renderedDescription('答案：' + answerItem)"
                    v-for="(answerItem, answerIndex) in item.answer"
                    :key="answerIndex"
                  ></p>
                </div>

                <!-- 解析 -->
                <div class="topicAnalysis">
                  <p
                    class="topicAnalysisText"
                    v-for="(resolveItem, resolveIndex) in item.resolve"
                    :key="resolveIndex"
                    v-html="$renderedDescription('解析：' + resolveItem)"
                  ></p>
                </div>

                <!-- 错误 -->
                <div class="error_txts">
                  <div
                    class="error_txt"
                    v-for="(errorItem, errorIndex) in errorTopicIndexs"
                    :key="errorIndex"
                    v-if="errorItem.index == index"
                  >
                    <div
                      v-for="(erritem, errindex) in errorItem.errors"
                      :key="errindex"
                    >
                      {{ erritem }}
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <!-- 缺省 -->
            <el-empty
              description="暂无题目"
              v-show="topicsShowArr.length == 0"
            ></el-empty>
          </div>
        </div>
      </div>
    </backContainer>
    <el-dialog
      custom-class="topicImportCheckDia"
      v-else
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      title="批量导入试题"
      :visible="open"
      width="1200px"
      append-to-body
      @close="cancel"
    >
      <div class="card" v-loading="loading">
        <!-- 顶部行 -->
        <div class="titleLine flexBet">
          <ancestorsNameDeal
            :text="ancestorsName"
            :maxLength="50"
            class="title shou"
          >
          </ancestorsNameDeal>
          <div class="btns flexColCenter">
            <!-- <div class="btn flexColCenter flexCen shou" @click="importTopic">
              <svg-icon class-name="btn_icon" icon-class="add_svg" />
              <div>批量导入试题</div>
            </div> -->
            <div
              class="btn bank_btn flexColCenter flexCen shou"
              @click="importTheQuestionBank"
            >
              <svg-icon class-name="btn_icon" icon-class="muttle_svg" />
              <div>导入题库</div>
            </div>
            <i @click="cancel" class="el-icon-close"></i>
          </div>
        </div>
        <!-- 检查区 -->
        <div class="flexBet checkBox">
          <!-- 输入区 -->
          <div class="edit_texteara">
            <div class="edit_texteara_titleline flexBet">
              <div class="left">输入区</div>
              <div
                class="right shou"
                @click="
                  topicImportEnterTheSpecificationOpen =
                    !topicImportEnterTheSpecificationOpen
                "
              >
                输入规范
              </div>
            </div>
            <div>
              <wangEditor
                ref="editor"
                @Blur="Blur"
                :isgetIndex="3"
                :editorValue.sync="content"
                height="calc(100vh - 328px)"
              />
            </div>
          </div>
          <!-- 检查区 -->
          <div class="topicBox">
            <div class="topicBox_titleline flexBet">
              <div class="left">
                检查区<span>(总计{{ topicsShowArr.length }}道题目)</span>
              </div>
            </div>
            <div class="flex error" v-if="errorTopicIndexs.length > 0">
              <div class="error_txt">
                {{ errorTopicIndexs.length }}道错误试题，请参照例题修改
              </div>
              <div
                class="next"
                @click="scrollToElement('cur')"
                v-if="errorTopicIndexs.length == 1"
              >
                查看错误
              </div>
              <div
                class="prev"
                @click="scrollToElement('prev')"
                v-if="errorCurIndex > 0 && errorTopicIndexs.length > 1"
              >
                查看上一处
              </div>
              <div
                class="next"
                @click="scrollToElement('next')"
                v-if="
                  errorCurIndex < errorTopicIndexs.length - 1 &&
                  errorTopicIndexs.length > 1
                "
              >
                查看下一处
              </div>
            </div>
            <div
              class="topicContain"
              ref="scrollContainer"
              @scroll="handleScroll"
              v-show="topicsShowArr.length > 0"
            >
              <div
                :id="`topic${index}`"
                :ref="`topic${index}`"
                class="topic"
                v-for="(item, index) in topicsShowArr"
                :key="index"
              >
                <!-- 题目 -->
                <div
                  v-if="difficultys.includes(item.difficulty[0])"
                  class="topicTitle"
                  v-html="
                    `<p>${index + 1} / ${topicsShowArr.length}.

                      <span class='color_orange'>【${topicType[item.type]}】
                    </span>
                    <span class='difficulty_item ${
                      difficultyBgClass[item.difficulty[0]]
                    }'>
                    ${item.difficulty[0]}
                    </span>${$renderedDescription(item.question.slice(3))}`
                  "
                ></div>
                <div
                  v-else
                  class="topicTitle"
                  v-html="
                    `<p>${index + 1} / ${topicsShowArr.length}.

                      <span class='color_orange'>【${topicType[item.type]}】
                    </span>
                    ${$renderedDescription(item.question.slice(3))}`
                  "
                ></div>
                <!-- 选项 -->
                <div
                  class="topicOptions"
                  v-if="item.type == 'multi_choice' || item.type == 'choice'"
                >
                  <div
                    class="topicOptionItem"
                    v-for="(option, optionIndex) in item.options"
                    :key="optionIndex"
                  >
                    <p
                      class="topicOptionA"
                      v-html="$renderedDescription(option)"
                    ></p>
                  </div>
                </div>
                <!-- 答案 -->
                <div class="topicAnswer">
                  <p
                    class="topicAnswerText"
                    v-html="$renderedDescription('答案：' + answerItem)"
                    v-for="(answerItem, answerIndex) in item.answer"
                    :key="answerIndex"
                  ></p>
                </div>

                <!-- 解析 -->
                <div class="topicAnalysis">
                  <p
                    class="topicAnalysisText"
                    v-for="(resolveItem, resolveIndex) in item.resolve"
                    :key="resolveIndex"
                    v-html="$renderedDescription('解析：' + resolveItem)"
                  ></p>
                </div>

                <!-- 错误 -->
                <div class="error_txts">
                  <div
                    class="error_txt"
                    v-for="(errorItem, errorIndex) in errorTopicIndexs"
                    :key="errorIndex"
                    v-if="errorItem.index == index"
                  >
                    <div
                      v-for="(erritem, errindex) in errorItem.errors"
                      :key="errindex"
                    >
                      {{ erritem }}
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <!-- 缺省 -->
            <el-empty
              description="暂无题目"
              v-show="topicsShowArr.length == 0"
            ></el-empty>
          </div>
        </div>
      </div>
    </el-dialog>
    <topicImportByFile
      @topicGet="topicGet"
      :open.sync="topicImportByFileOpen"
      :indexId.sync="indexId"
    ></topicImportByFile>
    <topicImportRepeat
      @importSuccess="topicImportRepeatImportSuccess"
      :open.sync="topicImportRepeatOpen"
      :arr="topicImportRepeatArr"
      :data="topicImportRepeatData"
      :indexId.sync="indexId"
    >
    </topicImportRepeat>
    <topicImportEnterTheSpecification
      @out="out"
      :open.sync="topicImportEnterTheSpecificationOpen"
    ></topicImportEnterTheSpecification>
    <topicImportSuccess
      @backTopic="cancel"
      @continueImporting="continueImporting"
      :componentType="componentType"
      :open.sync="topicImportSuccessOpen"
      :topicNums="topicImportSuccessTopicNums"
    ></topicImportSuccess>
  </div>
</template>

<script>
import ancestorsNameDeal from '@/components/ancestorsNameDeal'
import wangEditor from '@/components/Editor/wangEditor'
import topicImportEnterTheSpecification from '../components/topicImportEnterTheSpecification.vue'
import topicImportByFile from '../components/topicImportByFile.vue'
import topicImportRepeat from '../components/topicImportRepeat.vue'
import topicImportSuccess from '../components/topicImportSuccess.vue'
import { importDataimport, importDataValidate } from '@/api/questions/index.js'

export default {
  name: "topicImport",
  components: {
    wangEditor,
    topicImportByFile,
    topicImportRepeat,
    topicImportEnterTheSpecification,
    topicImportSuccess,
    ancestorsNameDeal,
  },
  props: {
    open: Boolean,
    componentType: {
      type: [String, Number],
      default: "2",
    },
    ancestorsName: [String, Number],
    indexId: [String, Number],
  },
  data() {
    return {
      topicImportEnterTheSpecificationOpen: false,

      content: "",
      topicImportSuccessOpen: false,
      topicImportSuccessTopicNums: {},
      topicImportRepeatArr: [],
      topicImportRepeatData: [],
      topicImportRepeatOpen: false,
      topicImportByFileOpen: false,
      topicType: {
        choice: "单选题",
        judgement: "判断题",
        filling: "填空题",
        multi_choice: "多选题",
        QA: "简答题",
        operation: "操作题",
      },
      difficultys: ["简单", "中等", "困难", "不限难度"],

      // 题目难易程度类名
      difficultyBgClass: {
        简单: "easy_bg",
        中等: "normal_bg",
        困难: "hard_bg",
        不限难度: "no_difficulty_bg",
      },

      // 错误的题目数组 index
      errorTopicIndexs: [],
      errorCurIndex: 0,
      // 用于显示右边的数组
      topicsShowArr: [],
      // 文件导入的题目数组
      topicFileImportArr: [],
      loading: false,
      action: "", // 'left' | 'right' | ''
    };
  },
  watch: {
    content(e) {
      this.topicsShowArr = [];
      this.topicsShowArr = this.richTextToArray(e);
      console.log("显示的题目数组", this.topicsShowArr);
      this.errorTopicIndexs = [];
      // 检查题目错误
      for (let i = 0; i < this.topicsShowArr.length; i++) {
        this.topicsShowArr[i].options = JSON.parse(
          this.topicsShowArr[i].options
        );
        // 0.所有题
        if (
          !this.topicsShowArr[i].question.replace("<p>", "").replace("</p>", "")
        ) {
          this.addErrorToArray(i, "缺少题干：请输入题干");
        }
        // 1.选项
        if (
          this.topicsShowArr[i].type == "choice" ||
          this.topicsShowArr[i].type == "multi_choice"
        ) {
          // 1.1验证选择题是否有选项
          if (this.topicsShowArr[i].options == null) {
            this.addErrorToArray(i, "缺少选项：请输入选择题选项");
          } else {
            if (this.topicsShowArr[i].options.length > 1) {
              // 验证选择题是否有选项
              let some = this.topicsShowArr[i].options.some((item) => {
                const content = item.replace(/<\/?p>/g, "").trim();
                return /^[A-D]\.$/.test(content);
              });
              if (some) {
                this.addErrorToArray(i, "缺少选项：请输入选择题选项");
              }
              // 验证选项是否重复
              let txt = this.checkOptionDuplicates(
                this.topicsShowArr[i].options
              );

              if (txt) {
                this.addErrorToArray(i, txt);
              }
            }
            // 选择题选项数量不够：选择题至少需要2个选项，请检查后重新输入
            else {
              this.addErrorToArray(
                i,
                "选择题选项数量不够：选择题至少需要2个选项，请检查后重新输入"
              );
            }
          }
        }
        // 答案-------------------
        // 1.选择题和多选题
        if (
          this.topicsShowArr[i].type == "choice" ||
          this.topicsShowArr[i].type == "multi_choice"
        ) {
          // 1.2单选题 检查答案 只允许有一个数组
          if (
            this.topicsShowArr[i].type == "choice" &&
            this.topicsShowArr[i].answer.length == 1 &&
            this.topicsShowArr[i].answer[0] !== ""
          ) {
            let answer = this.topicsShowArr[i].answer[0]
              .trim()
              .replace("\n", "");
            // 先判断答案是否为abc
            if (!/^[A-Z]+$/.test(answer)) {
              this.addErrorToArray(
                i,
                "答案错误：无法识别答案，请检查答案内容或格式是否有误后重新输入"
              );
            } else {
              // 单选题答案有多个：单选题只能有1个答案，请检查后重新输入
              if (answer.length > 1) {
                this.addErrorToArray(
                  i,
                  "单选题答案有多个：单选题只能有1个答案，请检查后重新输入"
                );
              }
              // 答案错误：无法识别答案
              if (this.topicsShowArr[i].options && answer.length == 1) {
                let letters = this.optionLetters(this.topicsShowArr[i].options);

                if (!letters.includes(answer)) {
                  this.addErrorToArray(
                    i,
                    "答案错误：无法识别答案，请检查答案内容或格式是否有误后重新输入"
                  );
                }
              }
            }
          }
          // 1.2多选题
          if (
            this.topicsShowArr[i].type == "multi_choice" &&
            this.topicsShowArr[i].answer.length == 1 &&
            this.topicsShowArr[i].answer[0] !== ""
          ) {
            let answer = this.topicsShowArr[i].answer[0]
              .trim()
              .replace("\n", "")
              .split("");
            // 先判断答案是否为abc
            if (!/^[A-Z]+$/.test(answer.join(""))) {
              this.addErrorToArray(
                i,
                "答案错误：无法识别答案，请检查答案内容或格式是否有误后重新输入"
              );
            } else {
              //多选题答案只有一个：多选题至少需要2个答案，请检查后重新输入
              if (answer.length < 2) {
                this.addErrorToArray(
                  i,
                  "多选题答案只有一个：多选题至少需要2个答案，请检查后重新输入"
                );
              } else {
                // 判断选项是否在选项内
                let letters = this.optionLetters(this.topicsShowArr[i].options);
                const isAIncluded = answer.every((item) =>
                  letters.includes(item)
                ); // true (A 和 B 都在)

                if (!isAIncluded) {
                  this.addErrorToArray(
                    i,
                    "无法识别答案，请检查答案内容或格式是否有误后重新输入"
                  );
                }
              }
            }
          }
        }

        // 3.填空题
        if (
          this.topicsShowArr[i].type == "filling" &&
          this.topicsShowArr[i].answer.length == 1 &&
          this.topicsShowArr[i].answer[0] !== ""
        ) {
          // 先获取答案
          const str = this.topicsShowArr[i].answer[0];
          // 1. 先根据 | 拆分
          const parts = str.split("|");

          // 2. 对每个部分处理 {} 和 $ 拆分
          const answers = parts
            .map((part) => {
              // 去掉 {}
              const cleaned = part.replace(/[{}]/g, "");
              // 根据 $ 拆分
              return cleaned.split("$");
            })
            .flat(); // 使用 flat() 展开嵌套数组
          // 在获取下划线数据
          const questionNum = this.topicsShowArr[i].question.match(/___/g)
            ? this.topicsShowArr[i].question.match(/___/g).length
            : 0;
          if (questionNum == 0) {
            this.addErrorToArray(
              i,
              "未识别到填空符，请检查后并插入填空符“___”"
            );
          } else {
            if (answers.length != questionNum) {
              this.addErrorToArray(
                i,
                "填空题答案数量与填空符数量不匹配，请检查后重新输入"
              );
            }
          }
        }
        // 4.判断题
        if (this.topicsShowArr[i].type == "judgement") {
          let judgementAnswers = [
            "正确",
            "错误",
            "对",
            "错",
            "是",
            "不",
            "yes",
            "no",
            "y",
            "n",
            "1",
            "0",
            "对的",
            "错的",
            "是的",
            "不是",
            "好",
            "不好",
            "可以",
            "不可以",
            "行",
            "不行",
            " ok",
            "no",
            "OK",
            "NO",
            "好的",
            "不对",
            "没错",
            "错",
            "错误",
          ];
          // 如果答案不是对和错
          if (
            this.topicsShowArr[i].answer.length == 1 &&
            this.topicsShowArr[i].answer[0] !== "" &&
            !judgementAnswers.includes(this.topicsShowArr[i].answer[0])
          ) {
            this.addErrorToArray(i, "判断题答案格式有误，请检查后重新输入");
          }
        }
        // 0.2答案
        if (
          (this.topicsShowArr[i].answer.length == 1 &&
            this.topicsShowArr[i].answer[0] == "") ||
          this.topicsShowArr[i].answer.length == 0
        ) {
          if (
            this.topicsShowArr[i].type == "choice" ||
            this.topicsShowArr[i].type == "multi_choice" ||
            this.topicsShowArr[i].type == "judgement" ||
            this.topicsShowArr[i].type == "filling"
          ) {
            this.addErrorToArray(i, "缺少答案：请输入答案");
          }
        } else if (this.topicsShowArr[i].answer.length > 1) {
          this.addErrorToArray(i, "答案字段重复");
        }
        // 0.1难度
        if (
          this.topicsShowArr[i].difficulty.length == 0 ||
          (this.topicsShowArr[i].difficulty.length == 1 &&
            this.topicsShowArr[i].difficulty[0] == "")
        ) {
          this.addErrorToArray(i, "缺少难度：请输入难度");
        } else if (this.topicsShowArr[i].difficulty.length > 1) {
          this.addErrorToArray(i, "难度字段重复");
        } else {
          if (!this.difficultys.includes(this.topicsShowArr[i].difficulty[0])) {
            this.addErrorToArray(
              i,
              "难度有误：无法识别难度，难度分为简单、中等、困难、不限难度，请检查后重新输入"
            );
          }
        }

        // 0.3解析

        if (this.topicsShowArr[i].resolve.length > 1) {
          this.addErrorToArray(i, "解析字段重复");
        }
      }

      if (this.errorTopicIndexs.length == 1) {
        const element = document.getElementById(this.errorTopicIndexs[0].index);
        if (element) {
          element.scrollIntoView({
            behavior: "smooth", // 平滑滚动
            block: "start", // 对齐到顶部
          });
        }
      }
      this.loading = false;
    },
    open(e) {
      if (e) {
        this.loading = true;
        let data = JSON.parse(localStorage.getItem("topicFileImportArr"));
        this.topicGet(data);
      }
    },
  },
  created() {},
  mounted() {},
  methods: {
    // 进入左或右
    onEnter(side) {
      this.action = side;
    },
    // 离开任意区域
    onLeave() {
      this.action = "";
    },
    handleScroll(event) {
      if (this.action !== "right") return;

      const container = event.target;
      const scrollTop = container.scrollTop;

      let cumulativeHeight = 0; // 累计高度：前面所有题的高度（不含间距）
      let curIndex = 0;

      for (let i = 0; i < this.topicsShowArr.length; i++) {
        // 获取当前题的 DOM 元素
        const elements = this.$refs[`topic${i}`];
        const element = elements?.[0];

        if (!element) {
          // 如果元素未渲染，假设一个默认高度（如 200px），不加间距
          cumulativeHeight += 200;
          continue;
        }

        const height = element.offsetHeight;
        const top = cumulativeHeight; // 当前题的顶部位置

        // 如果当前滚动位置 >= 当前题顶部，说明它已经进入视口
        // 我们取最后一个满足条件的题（即当前主显示题）
        if (scrollTop >= top - 1) {
          curIndex = i;
        } else if (scrollTop < top) {
          // 由于题目顺序排列，一旦当前题的 top 都大于 scrollTop
          // 后面的题更不可能，提前退出
          break;
        }

        // 累加当前题的高度（⚠️ 不再 +32 间距）
        cumulativeHeight += height;
      }

      console.log("当前显示的题目索引:", curIndex + 1);
      this.$refs.editor.scrollToId(curIndex + 1);
    },
    continueImporting() {
      console.log("continueImporting");

      this.content = "";
      this.topicImportByFileOpen = true;
    },
    // 文件导入题目获取 题目数组
    topicGet(e) {
      for (let i = 0; i < e.length; i++) {
        if (e[i].type == "choice" || e[i].type == "multi_choice") {
          e[i].options = this.normalizeLetterDots(e[i].options);
        }
      }

      this.topicFileImportArr = e;
      this.topicArrToText();
      this.normalizeQuestions(this.content);
    },
    // 错误函数处理
    addErrorToArray(index, errorMessage) {
      // 查找是否已存在相同 index 的对象
      const existingItem = this.errorTopicIndexs.find(
        (item) => item.index === index
      );

      if (existingItem) {
        // 如果已存在，将错误信息推入 errors 数组
        existingItem.errors.push(errorMessage);
      } else {
        // 如果不存在，新建一个对象
        this.errorTopicIndexs.push({
          index: index,
          errors: [errorMessage],
        });
      }
    },
    // 插入示例
    out(e) {
      if (!this.content.replace(/<[^>]+>/g, "")) {
        this.content += e;
      } else {
        this.$refs.editor.insert(e);
      }

      this.normalizeQuestions(this.content);
    },
    // 题目转富文本
    topicArrToText() {
      let content = "";
      for (let index = 0; index < this.topicFileImportArr.length; index++) {
        let topic = "";
        topic += `<p>${index + 1}.【${
          this.topicType[this.topicFileImportArr[index].type]
        }】${this.topicFileImportArr[index].question}</p>
            `;
        if (
          this.topicFileImportArr[index].type == "choice" ||
          this.topicFileImportArr[index].type == "multi_choice"
        ) {
          let options = JSON.parse(this.topicFileImportArr[index].options);
          for (let j = 0; j < options.length; j++) {
            topic += `<p>${options[j]}</p>`;
          }
        }
        topic += `
            <p>答案:${
              this.topicFileImportArr[index].answer
                ? this.topicFileImportArr[index].answer
                : ""
            }</p>
            <p>难度:${
              this.topicFileImportArr[index].difficulty
                ? this.topicFileImportArr[index].difficulty
                : ""
            }</p>
            <p>解析:${
              this.topicFileImportArr[index].resolve
                ? this.topicFileImportArr[index].resolve
                : ""
            }</p>
            `;
        content += topic;
      }
      this.$nextTick(() => {
        this.content += content;
      });
    },
    // 富文本题目排列 序号
    normalizeQuestions(richText) {
      // 1. 先分割所有题目（不依赖序号）
      const questionRegex =
        /(<p[^>]*>)?\s*(\d+\.\s*)?【(单选题|多选题|填空题|判断题|简答题|操作题)】/g;
      const matches = [];
      let match;

      // 找到所有题目起始位置
      while ((match = questionRegex.exec(richText)) !== null) {
        matches.push({
          index: match.index,
          prefix: match[1] || "", // 保存<p>标签（如果有）
          length: match[0].length,
        });
      }

      // 2. 分割原始文本
      const sections = [];
      for (let i = 0; i < matches.length; i++) {
        const start = matches[i].index;
        const end =
          i < matches.length - 1 ? matches[i + 1].index : richText.length;
        sections.push({
          content: richText.substring(start, end),
          prefix: matches[i].prefix,
        });
      }

      // 3. 重新编号处理
      let result = "";
      sections.forEach((section, index) => {
        // 移除旧序号（保留<p>标签）
        const cleaned = section.content
          .replace(/^(<p[^>]*>)?\s*\d+\.\s*/, section.prefix || "")
          .trim();

        // 添加新序号
        const numbered = section.prefix
          ? cleaned.replace(/^(<p[^>]*>)/, `$1${index + 1}.`)
          : `${index + 1}. ${cleaned}`;

        // let str =
        //   numbered.slice(0, 2) + `  id="topic${index}"` + numbered.slice(2);
        // console.log("添加新序号", str);
        result += numbered;
      });
      this.content = result;
    },
    Blur(e) {
      console.log("blur", e);
      this.normalizeQuestions(this.content);
    },
    // 提取选项字母（A, B, C, D, G）
    optionLetters(options) {
      if (options) {
        return Object.values(options)
          .map((html) => {
            const match = html.match(/<p>([A-Z])\./);
            return match ? match[1] : null; // 直接返回大写的字母（A-Z）
          })
          .filter(Boolean); // 过滤无效值
      }
    },
    // 检测选项是否重复
    // 检测选项是否重复（统一显示为"内容重复"）
    // 检测选项是否重复和字母顺序是否正确
    checkOptionDuplicates(options) {
      // 确保options是数组（处理各种输入格式）
      let optionsArray;
      if (Array.isArray(options)) {
        optionsArray = options;
      } else if (typeof options === "string") {
        try {
          optionsArray = JSON.parse(options);
        } catch (e) {
          console.error("输入的选项格式不正确");
          return "选项格式不正确";
        }
      } else {
        optionsArray = [];
      }

      const letterMap = {}; // 存储字母重复
      const contentMap = {}; // 存储内容重复
      const allDuplicateGroups = new Set(); // 使用Set避免重复记录
      const letters = []; // 存储所有选项字母用于顺序检查

      // 增强的内容提取函数
      const extractInfo = (option) => {
        // 处理未闭合的HTML标签
        const cleanText = option.replace(/<\/?[^>]+(>|$)/g, "");

        // 提取选项字母（支持A. A、 A）等多种格式）
        const letterMatch = cleanText.match(/^([A-Z])[.、]?\s*/);
        const letter = letterMatch ? letterMatch[1] : "";

        // 提取实际内容（去除选项字母）
        const content = cleanText.replace(/^[A-Z][.、]?\s*/, "").trim();

        return { letter, content };
      };

      // 构建字母和内容映射表
      optionsArray.forEach((option) => {
        const { letter, content } = extractInfo(option);

        // 检查字母重复
        if (letter) {
          if (!letterMap[letter]) {
            letterMap[letter] = [];
          }
          letterMap[letter].push(letter);
          letters.push(letter); // 收集字母用于顺序检查
        }

        // 检查内容重复
        if (content) {
          if (!contentMap[content]) {
            contentMap[content] = new Set(); // 使用Set避免重复字母
          }
          contentMap[content].add(letter);
        }
      });

      // 收集所有字母重复组（格式：A、A）
      for (const letter in letterMap) {
        if (letterMap[letter].length > 1) {
          allDuplicateGroups.add([letter, letter].join("、"));
        }
      }

      // 收集所有内容重复组（格式：A、B）
      for (const content in contentMap) {
        if (contentMap[content].size > 1) {
          allDuplicateGroups.add(
            Array.from(contentMap[content]).sort().join("、")
          );
        }
      }

      // 如果有重复，优先返回重复错误
      if (allDuplicateGroups.size > 0) {
        return `选择题选项重复：识别到选项${Array.from(allDuplicateGroups).join(
          "；"
        )}内容重复，请检查后重新输入`;
      }

      // 检查字母顺序是否正确（A-Z连续）
      if (letters.length > 0) {
        // 检查是否从大写字母'A'开始
        if (letters[0] !== "A") {
          return "选项必须从A开始";
        }
        const isAlphabeticalOrder = letters.every((letter, index) => {
          if (index === 0) return true; // 第一个字母无需比较
          const prevCharCode = letters[index - 1].charCodeAt(0);
          const currCharCode = letter.charCodeAt(0);
          return currCharCode === prevCharCode + 1; // 当前字母必须比前一个大 1
        });

        if (!isAlphabeticalOrder) {
          Array.from(
            { length: letters.length },
            (_, i) => String.fromCharCode(letters[0].charCodeAt(0) + i)
          )
          return `选项不连续或者缺失`;
        }
      }

      return ""; // 没有错误

    },
    wangEditorScroll(e) {
      console.log("当前:", e);
      this.scrollToElement("scroll", e - 1);
    },
    scrollToElement(type, index) {
      let toId = "";
      if (type == "prev") {
        this.errorCurIndex--;
        toId = this.errorTopicIndexs[this.errorCurIndex].index;
      } else if (type == "next") {
        this.errorCurIndex++;
        toId = this.errorTopicIndexs[this.errorCurIndex].index;
      } else if (type == "cur") {
        toId = this.errorTopicIndexs[0].index;
      } else {
        toId = index;
      }
      const element = document.getElementById("topic" + toId);
      if (element) {
        element.scrollIntoView({
          behavior: "smooth", // 平滑滚动
          block: "start", // 对齐到顶部
        });
      }
    },
    // 富文本转数组
    richTextToArray(richText) {
      // 1. 按题目分割（兼容带序号和不带序号的情况）
      const questionRegex =
        /<p>\s*(?:\d+\.\s*)?【(?:单选题|多选题|填空题|判断题|简答题|操作题)】/g;

      // 2. 找到所有题目起始位置
      const splitPoints = [];
      let match;
      while ((match = questionRegex.exec(richText)) !== null) {
        splitPoints.push(match.index);
      }

      // 3. 分割题目
      const questions = [];
      for (let i = 0; i < splitPoints.length; i++) {
        const start = splitPoints[i];
        const end =
          i < splitPoints.length - 1 ? splitPoints[i + 1] : richText.length;
        questions.push(richText.substring(start, end).trim());
      }

      const result = [];
      for (const q of questions) {
        try {
          // 提取题目类型
          const typeMatch = q.match(
            /【(单选题|多选题|填空题|判断题|简答题|操作题)】/
          );
          if (!typeMatch) continue;
          const type = {
            单选题: "choice",
            多选题: "multi_choice",
            填空题: "filling",
            判断题: "judgement",
            简答题: "QA",
            操作题: "operation",
          }[typeMatch[1]];

          // 提取题干部分(提取到下一个<p>数字.【xx】或者 <p>【xx】，xx可以是单选题|多选题|填空题|判断题|简答题|操作题之前，或者是 <p>答案: <p>分数:  <p>难度:  <p>解析: <p>英文. 之前)
          const questionMatch = q.match(
            /<p>\s*\d*\.?\s*【(?:单选题|多选题|填空题|判断题|简答题|操作题)】\s*([\s\S]*?)(?=\s*<p>\s*\d+\.\s*【|<p>\s*(?:答案|分数|难度|解析)\s*[:：]|<p>\s*[A-Z][.．]|$)/i
          );
          const question = questionMatch ? questionMatch[1].trim() : "";

          // 提取所有答案（可能有多个） (提取到下一个<p>数字.【xx】或者 <p>【xx】，xx可以是单选题|多选题|填空题|判断题|简答题|操作题之前，或者是 <p>答案: <p>分数:  <p>难度:  <p>解析: <p>英文（A-Z）. 之前)
          const answerMatches = [
            ...q.matchAll(
              /<p>\s*答案\s*[:：]\s*([\s\S]*?)(?=\s*<p>\s*(?:分数|难度|解析|答案)\s*[:：]|<p>\s*\d+\.\s*【|<p>\s*【(?:单选题|多选题|填空题|判断题|简答题|操作题)】|$)/gis
            ),
          ];
          const answers =
            answerMatches.length > 0
              ? answerMatches.map((match) => {
                  let content = match[1].trim();
                  if (
                    type != "choice" &&
                    type != "multi_choice" &&
                    type != "judgement"
                  ) {
                    // 在每个解析内容前面加上<p>标签
                    content = "<p>" + content;
                    // 检查是否以</p>结尾，如果不是则补上
                    if (!content.endsWith("</p>")) {
                      content += "</p>";
                    }
                  } else {
                    content = content.replace(/<\/p>/g, "");
                  }

                  return content;
                })
              : [];

          // 提取选项（仅选择题/多选题）
          let options = null;
          if (type === "choice" || type === "multi_choice") {
            // 匹配所有选项及其内容块
            const optionBlocks = q.split(/<p>\s*([A-Z])\./).slice(1);
            const optionParts = [];

            for (let i = 0; i < optionBlocks.length; i += 2) {
              const letter = optionBlocks[i];
              let contentBlock = optionBlocks[i + 1];

              // 查找下一个选项或特殊标记的起始位置
              const nextOptionMatch = contentBlock.match(
                /<\/p>\s*<p>\s*([A-Z]\.|答案[:：]|分数[:：]|难度[:：]|解析[:：]|\d+\.\s*【)/
              );

              if (nextOptionMatch) {
                const cutIndex = nextOptionMatch.index;
                contentBlock = contentBlock.substring(0, cutIndex);
              }

              // 重建完整的选项HTML并清理多余的闭合标签
              const fullOption = `<p>${letter}.${contentBlock}</p>`;
              const fullOptionAfter = fullOption
                .replace(/<\/p><\/p>/g, "</p>")
                .replace(/<p><\/p>/g, "");

              if (fullOptionAfter.trim().length > 5) {
                // 简单过滤空选项
                optionParts.push(fullOptionAfter);
              }
            }

            options =
              optionParts.length > 0 ? JSON.stringify(optionParts) : null;
          }

          // 提取所有分数（可能有多个）
          const scoreMatches = [...q.matchAll(/<p>\s*分数[:：](\d+)/g)];
          const scores = scoreMatches.map((match) => parseInt(match[1]));

          // 提取所有难度（可能有多个）
          const difficultyMatches = [
            ...q.matchAll(
              /<p>\s*难度\s*[:：]\s*([\s\S]*?)(?=\s*<p>\s*(?:分数|难度|解析|答案)\s*[:：]|<p>\s*\d+\.\s*【|<p>\s*【(?:单选题|多选题|填空题|判断题|简答题|操作题)】|$)/gis
            ),
          ];
          const difficulties = difficultyMatches.map((match) =>
            match[1].trim().replace(/<\/?p>/g, "")
          );

          // 提取所有解析内容（保留原始HTML格式）
          // 提取所有解析内容（保留原始HTML格式）
          const resolveMatches = [
            ...q.matchAll(
              /<p>\s*解析\s*[:：]\s*([\s\S]*?)(?=\s*<p>\s*(?:分数|难度|解析|答案)\s*[:：]|<p>\s*\d+\.\s*【|<p>\s*【(?:单选题|多选题|填空题|判断题|简答题|操作题)】|$)/gis
            ),
          ];
          const resolves =
            resolveMatches.length > 0
              ? resolveMatches.map((match) => {
                  let content = match[1].trim();
                  // 在每个解析内容前面加上<p>标签
                  content = "<p>" + content;
                  // 检查是否以</p>结尾，如果不是则补上
                  if (!content.endsWith("</p>")) {
                    content += "</p>";
                  }
                  return content;
                })
              : [];

          result.push({
            type,
            question: question ? "<p>" + question : "",
            options: options ? options : null,
            answer: answers.length > 0 ? answers : [], // 返回答案数组
            score: scores.length > 0 ? scores : [], // 返回分数数组
            difficulty: difficulties.length > 0 ? difficulties : [], // 返回难度数组
            resolve: resolves.length > 0 ? resolves : [], // 返回解析数组
            id: null,
            uuid: "",
            resultType: "success",
            msg: "",
          });
        } catch (error) {
          console.error("题目解析错误:", error);
          result.push({
            type: "error",
            question: "",
            options: null,
            answer: [],
            score: [],
            difficulty: [],
            resolve: [],
            id: null,
            uuid: "",
            resultType: "error",
            msg: error.message,
          });
        }
      }
      console.log("result", result);
      return result;
    },
    // 导入时用于 检测字母是否重复 比如A.A.
    normalizeLetterDots(jsonStr) {
      // 1. 解析 JSON 字符串为数组
      const arr = JSON.parse(jsonStr);

      // 2. 处理每个字符串元素
      const normalizedArr = arr.map((item) => {
        // 匹配所有 "字母." 模式（如 A. B. C.）
        const matches = item.match(/[A-Z]\./g);

        if (matches && matches.length > 1) {
          // 如果发现多个 "字母."，只保留第一个
          const firstLetterDot = matches[0];
          // 替换掉后续多余的 "字母."
          return item.replace(
            new RegExp(`(${firstLetterDot}\\s*)+`, "g"),
            firstLetterDot + " "
          );
        }

        return item;
      });

      // 3. 返回处理后的 JSON 字符串
      return JSON.stringify(normalizedArr);
    },
    // 提交题目数组转换
    transformQuestions(originalQuestions) {
      console.log("提交题目数组转换", originalQuestions);
      return originalQuestions.map((question, index) => {
        // 转换题目类型为数字
        const typeMap = {
          choice: 0, // 单选题
          multi_choice: 1, // 多选题
          filling: 3, // 填空题
          judgement: 2, // 判断题
          QA: 4, // 简答题
          operation: 5, // 简答题
        };

        // 转换难度为数字
        const difficultyMap = {
          简单: 0,
          中等: 1,
          困难: 2,
          不限难度: 3,
        };

        // 处理选项
        let options = [];
        if (
          question.type == "judgement" ||
          question.type == "operation" ||
          question.type == "QA"
        ) {
          options = [
            {
              optionLabel: "A",
              optionValue: question.answer[0],
              trueOption: true,
            },
          ];
        }
        if (question.type == "filling") {
          // 先获取答案
          const str = question.answer[0];
          // 1. 先根据 | 拆分
          const parts = str.split("|");

          // 2. 对每个部分处理 {} 和 $ 拆分
          const answers = parts
            .map((part) => {
              // 去掉 {}
              const cleaned = part.replace(/[{}]/g, "");
              // 根据 $ 拆分
              return cleaned.split("$");
            })
            .flat(); // 使用 flat() 展开嵌套数组
          // 生成填空题选项
          for (let i = 0; i < answers.length; i++) {
            options.push({
              optionValue: answers[i], // 填空位置编号
              optionLabel: i, // 从0开始的索引
              trueOption: true, // 填空题每个空都是必填
            });
          }
        }
        if (
          question.options &&
          (question.type == "choice" || question.type == "multi_choice")
        ) {
          const correctAnswers = question.answer[0]
            .split("")
            .map((a) => a.trim());

          question.options.forEach((opt, i) => {
            // 提取选项内容和标签
            const match = opt.match(/<p>([A-Z])\.(.*?)<\/p>/);
            if (match) {
              const optionLabel = match[1];
              const optionValue = match[2].trim();

              options.push({
                optionValue: optionValue,
                optionLabel: optionLabel,
                trueOption: correctAnswers.includes(optionLabel),
                group: null,
                id: i + 1,
              });
            }
          });
        }

        return {
          ccTopicOptionList: options,
          containerId: 0,
          content: question.question.trim(),
          contentPic: "",
          createBy: null,
          createTime: null,
          difficulty: difficultyMap[question.difficulty[0]],
          id: null,
          indexId: 154961 + index,
          needDevice: null,
          optionCount: options.length,
          parentTopicId: null,
          radioLabel: null,
          resolve: question.resolve[0],
          resolvePic: "",
          score: 0,
          status: null,
          titleId: 0,
          topicType: typeMap[question.type],
        };
      });
    },
    // 从重复试题检测页面 导入成功返回
    topicImportRepeatImportSuccess(data) {
      this.topicImportSuccessTopicNums = data;
      this.topicImportSuccessOpen = true;
      this.$emit("refreshTopic");
      this.cancel();
    },
    // 导入题库
    async importTheQuestionBank() {
      if (this.topicsShowArr.length == 0) {
        this.$modal.msgWarning("导入内容不能为空");
        return false;
      }
      console.log("导入题库");
      if (this.errorTopicIndexs.length > 0) {
        // 提示存在错误
        this.$modal.msgError("存在错误试题，请检查并修改后再导入");
        return false;
      }
      try {
        this.loading = true;
        let questionArray = JSON.parse(JSON.stringify(this.topicsShowArr));
        let data = this.transformQuestions(questionArray);

        let res = await importDataValidate(data);
        if (res.code == 200) {
          if (res.data.length > 0) {
            this.topicImportRepeatOpen = true;
            this.topicImportRepeatArr = res.data;
            this.topicImportRepeatData = data;
          } else {
            let success = await importDataimport(this.indexId, 1, data);
            if (success.code == 200) {
              this.$modal.msgSuccess("导入成功！");
              this.$emit("refreshTopic");
              this.topicImportSuccessTopicNums = success.data;
              this.topicImportSuccessOpen = true;
            }
          }
        }
      } finally {
        this.loading = false;
      }
    },
    // 取消按钮
    cancel() {
      this.$emit("update:open", false);
    },
  },
};
</script>
<style scoped lang='scss'>
::v-deep .color_orange {
  color: #ef7d00 !important;
}
::v-deep .easy_bg {
  background: #6dd400 !important;
}
::v-deep .normal_bg {
  background: #f7b500 !important;
}
::v-deep .hard_bg {
  background: #fa6400 !important;
}
::v-deep .no_difficulty_bg {
  background: #0091ff !important;
}
::v-deep .difficulty_item {
  display: inline-block !important;
  font-family: PingFangSC, PingFang SC, sans-serif;
  font-weight: 500;
  font-size: 12px;
  color: #ffffff;
  padding: 0 4px;
  border-radius: 2px;
  box-sizing: border-box;
}
::v-deep .topicImportCheckDia .el-dialog__header {
  display: none !important;
}
::v-deep .topicImportCheckDia .el-dialog__body {
  padding: 0 !important;
}
@mixin btn_plain($bg_color, $color) {
  background: $bg_color;
  color: $color;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  user-select: none;

  &:active,
  &:hover {
    background: darken($bg_color, 5%);
    color: darken($color, 18%);
  }

  &:disabled {
    background: lighten($bg_color, 5%);
    color: lighten($color, 40%);
  }

  @content;
}

@import "../../../assets/styles/mixin.scss";
.card {
  margin: 22px auto 0 auto;
  width: 1200px;
  height: calc(100vh - 120px);
  background: #ffffff;
  border-radius: 16px;
  box-sizing: border-box;
  box-shadow: 0 0 8px 0 rgba(9, 28, 61, 0.17);
  .titleLine {
    border-bottom: 1px solid #eeeeee;
    height: 58px;
    box-sizing: border-box;
    .title {
      padding: 23px 0 0 16px;
      font-family: PingFangSC, PingFang SC, sans-serif;
      font-weight: 600;
      font-size: 16px;
      color: #333333;
      line-height: 22px;
      text-align: left;
      font-style: normal;
    }
    .btns {
      .btn:nth-of-type(1) {
        @include plain_hover(#f3faff, #1677ff, #ffffff) {
          width: 130px;
          height: 32px;
          border-radius: 8px;
          border: 1px solid #1677ff;
          font-family: PingFangSC, PingFang SC, sans-serif;
          font-weight: 400;
          font-size: 14px;
          font-style: normal;
          margin-right: 16px;
        }
        .btn_icon {
          color: #1677ff;
          width: 16px;
          height: 16px;
          margin-right: 4px;
        }
        &:hover {
          .btn_icon {
            color: #ffffff;
          }
        }
        &:active {
          .btn_icon {
            color: #ffffff;
          }
        }
      }
      .btn:nth-of-type(2) {
        @include plain_hover(#fff8ee, #e6a23b, #ffffff) {
          width: 102px;
          height: 32px;
          border-radius: 8px;
          border: 1px solid #e6a23b;
          font-family: PingFangSC, PingFang SC, sans-serif;
          font-weight: 400;
          font-size: 14px;
          font-style: normal;
          margin-right: 24px;
        }
        .btn_icon {
          color: #e6a23b;
          width: 16px;
          height: 16px;
          margin-right: 4px;
        }
        &:hover {
          .btn_icon {
            color: #ffffff;
          }
        }
        &:active {
          .btn_icon {
            color: #ffffff;
          }
        }
      }
      .el-icon-close {
        color: #333333;
        margin-right: 20px;
        cursor: pointer;
        font-size: 20px;
      }
    }
  }
  .checkBox {
    margin-top: 5px;
    .edit_texteara {
      display: flex;
      flex-direction: column;

      width: 600px;
      box-sizing: border-box;
      padding: 0 14px 0 25px;
      border-right: 1px solid #edeff0;
      .edit_texteara_titleline {
        padding: 13px 0 9px 0;
        .left {
          font-family: PingFangSC, PingFang SC, sans-serif;
          font-weight: 500;
          font-size: 16px;
          color: #333333;
          line-height: 22px;
          text-align: left;
          font-style: normal;
        }
        .right {
          font-family: PingFangSC, PingFang SC, sans-serif;
          font-weight: 500;
          font-size: 14px;
          color: #1677ff;
          line-height: 22px;
          text-align: right;
          font-style: normal;
          text-decoration-line: underline;
        }
      }
    }
    .error_txts {
      .error_txt {
        font-family: PingFangSC, PingFang SC, sans-serif;
        font-weight: 400;
        font-size: 14px;
        color: #e95756;
        line-height: 20px;
        text-align: left;
        font-style: normal;
      }
    }
    .topicBox {
      padding: 0 0 0 24px;
      width: 600px;
      height: calc(100vh - 248px + 44px);
      display: flex;
      flex-direction: column;
      .error {
        margin: 11px 0;
        .error_txt {
          font-family: PingFangSC, PingFang SC, sans-serif;
          font-weight: 400;
          font-size: 14px;
          color: #e95756;
          line-height: 20px;
          text-align: left;
          font-style: normal;
        }
        .prev {
          @include btn_plain(#ffffff, #666666) {
            margin: 0 0 0 16px;
            width: 83px;
            text-align: center;
            height: 24px;
            line-height: 24px;
            box-sizing: border-box;
            border-radius: 2px;
            border: 1px solid #edeff0;
            font-size: 14px;
            font-family: PingFangSC-Regular, PingFang SC, sans-serif;
            font-weight: 400;
          }
        }
        .next {
          @include btn_plain(#28b28b, #ffffff) {
            margin: 0 0 0 16px;
            width: 83px;
            text-align: center;
            height: 24px;
            line-height: 24px;
            box-sizing: border-box;
            border-radius: 2px;
            border: 1px solid #edeff0;
            font-size: 14px;
            font-family: PingFangSC-Regular, PingFang SC, sans-serif;
            font-weight: 400;
          }
        }
      }
      .topicBox_titleline {
        padding: 13px 0 9px 0;
        .left {
          font-family: PingFangSC, PingFang SC, sans-serif;
          font-weight: 500;
          font-size: 16px;
          color: #333333;
          line-height: 22px;
          text-align: left;
          font-style: normal;
          span {
            font-size: 14px;
          }
        }
      }
      .topicContain {
        position: relative;
        flex: 1;
        padding-right: 31px;
        overflow-y: auto;
        .topic:nth-of-type(1) {
          padding-top: 0;
        }
        .topic {
          padding-top: 64px;
          .topicTitle {
            word-wrap: break-word; /* 长单词换行 */
            overflow-wrap: break-word; /* 现代标准 */
            overflow: hidden;
            width: 541px;
            font-family: PingFangSC, PingFang SC, sans-serif;
            font-weight: 500;
            font-size: 14px;
            color: #333333;
            line-height: 22px;
            text-align: left;
            font-style: normal;
            .topicType {
              margin-left: 5px;
              color: #ef7d00;
            }
            .topicdiff {
              margin-top: 4px;
              margin-right: 5px;
              padding: 0 4px;
              height: 16px;
              line-height: 16px;
              font-family: PingFangSC, PingFang SC, sans-serif;
              font-weight: 500;
              font-size: 12px;
              color: #ffffff;
              text-align: left;
              font-style: normal;
            }
            .topicTitleText {
            }
          }
          .topicOptions {
            margin-top: 20px;
            .topicOptionItem:nth-of-type(1) {
              margin-top: 0;
            }
            .topicOptionItem {
              width: 100%;
              word-wrap: break-word; /* 长单词换行 */
              overflow-wrap: break-word; /* 现代标准 */
              overflow: hidden;
              margin-top: 10px;
              font-family: PingFangSC, PingFang SC, sans-serif;
              font-weight: 400;
              font-size: 16px;
              color: #333333;
              line-height: 22px;
              text-align: left;
              font-style: normal;
              .topicOptionA {
              }
            }
          }
          .topicAnswer {
            word-wrap: break-word; /* 长单词换行 */
            overflow-wrap: break-word; /* 现代标准 */
            overflow: hidden;
            width: 541px;
            margin-top: 18px;
            font-family: PingFangSC, PingFang SC, sans-serif;
            font-weight: 400;
            font-size: 16px;
            color: #28b28b;
            line-height: 22px;
            text-align: left;
            font-style: normal;
            .topicAnswerText {
            }
          }
          .topicScore {
            margin-top: 12px;
            font-family: PingFangSC, PingFang SC, sans-serif;
            font-weight: 400;
            font-size: 16px;
            color: #333333;
            line-height: 22px;
            text-align: left;
            font-style: normal;
          }
          .topicDifficulty {
            margin-top: 12px;
            font-family: PingFangSC, PingFang SC, sans-serif;
            font-weight: 400;
            font-size: 16px;
            color: #333333;
            line-height: 22px;
            text-align: left;
            font-style: normal;
          }
          .topicAnalysis {
            word-wrap: break-word; /* 长单词换行 */
            overflow-wrap: break-word; /* 现代标准 */
            overflow: hidden;
            width: 541px;
            margin-top: 12px;
            font-family: PingFangSC, PingFang SC, sans-serif;
            font-weight: 400;
            font-size: 16px;
            color: #333333;
            line-height: 22px;
            text-align: left;
            font-style: normal;
            .topicAnalysisText {
            }
          }
        }
      }
    }
  }
}
</style>
